/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package mil.nga.giat.elasticsearch;
import java.io.IOException;
import java.util.List;
import java.util.logging.Level;
import mil.nga.giat.data.elasticsearch.ElasticAttribute;
import mil.nga.giat.data.elasticsearch.ElasticDataStore;
import mil.nga.giat.data.elasticsearch.ElasticLayerConfiguration;
import org.apache.wicket.Component;
import org.apache.wicket.MarkupContainer;
import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.head.OnLoadHeaderItem;
import org.apache.wicket.markup.html.panel.Fragment;
import org.apache.wicket.model.IModel;
import org.geoserver.catalog.Catalog;
import org.geoserver.catalog.CatalogBuilder;
import org.geoserver.catalog.DataStoreInfo;
import org.geoserver.catalog.FeatureTypeInfo;
import org.geoserver.catalog.LayerInfo;
import org.geoserver.catalog.ResourceInfo;
import org.geoserver.web.GeoServerApplication;
import org.geoserver.web.data.resource.ResourceConfigurationPage;
import org.geoserver.web.data.resource.ResourceConfigurationPanel;
import org.geoserver.web.wicket.ParamResourceModel;
import org.geotools.feature.NameImpl;
import org.opengis.feature.type.Name;
/**
* Resource configuration panel to show a link to open Elasticsearch attribute
* modal dialog <br> If the Elasticsearch attribute are not configured for
* current layer, the modal dialog will be open at first resource configuration
* window opening <br> After modal dialog is closed the resource page is
* reloaded and feature configuration table updated
*
*/
public class ElasticConfigurationPanel extends ResourceConfigurationPanel {
private static final long serialVersionUID = 3382530429105288433L;
private LayerInfo _layerInfo;
private ElasticLayerConfiguration _layerConfig;
/**
* Adds Elasticsearch configuration panel link, configure modal dialog and
* implements modal callback.
*
* @see {@link ElasticConfigurationPage#done}
*/
public ElasticConfigurationPanel(final String panelId, final IModel model) {
super(panelId, model);
final FeatureTypeInfo fti = (FeatureTypeInfo) model.getObject();
final ModalWindow modal = new ModalWindow("modal");
modal.setInitialWidth(800);
modal.setTitle(new ParamResourceModel("modalTitle", ElasticConfigurationPanel.this));
if (fti.getMetadata().get(ElasticLayerConfiguration.KEY) == null) {
modal.add(new OpenWindowOnLoadBehavior());
}
modal.setContent(new ElasticConfigurationPage(panelId, model) {
@Override
void done(AjaxRequestTarget target, LayerInfo layerInfo,
ElasticLayerConfiguration layerConfig) {
_layerInfo = layerInfo;
_layerConfig = layerConfig;
try {
saveLayer((FeatureTypeInfo) getResourceInfo());
} catch (IOException e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
error(new ParamResourceModel("creationFailure", this, e).getString());
}
MarkupContainer parent = ElasticConfigurationPanel.this.getParent();
while (!(parent == null || parent instanceof ResourceConfigurationPage)) {
parent = parent.getParent();
}
if (parent != null && parent instanceof ResourceConfigurationPage) {
ResourceInfo ri = ElasticConfigurationPanel.this.getResourceInfo();
((ResourceConfigurationPage)parent).updateResource(ri, target);
}
modal.close(target);
}
});
add(modal);
AjaxLink findLink = new AjaxLink("edit") {
@Override
public void onClick(AjaxRequestTarget target) {
modal.show(target);
}
};
final Fragment attributePanel = new Fragment("esPanel", "esPanelFragment", this);
attributePanel.setOutputMarkupId(true);
add(attributePanel);
attributePanel.add(findLink);
}
/*
* Open modal dialog on window load
*/
private class OpenWindowOnLoadBehavior extends AbstractDefaultAjaxBehavior {
@Override
protected void respond(AjaxRequestTarget target) {
ModalWindow window = (ModalWindow) getComponent();
window.show(target);
}
@Override
public void renderHead(Component component, IHeaderResponse response) {
response.render(OnLoadHeaderItem.forScript(getCallbackScript().toString()));
}
}
private void saveLayer(FeatureTypeInfo ft) throws IOException {
GeoServerApplication app = (GeoServerApplication) getApplication();
Catalog catalog = app.getCatalog();
String namespace = ft.getNamespace().getURI();
Name qualifiedName = new NameImpl(namespace, _layerInfo.getName());
LayerInfo layerInfo = catalog.getLayerByName(qualifiedName);
boolean isNew = ft.getId() == null || app.getCatalog().getResource(ft.getId(),ResourceInfo.class) == null;
FeatureTypeInfo typeInfo;
if (layerInfo == null || isNew) {
// New
DataStoreInfo dsInfo;
dsInfo = catalog.getStore(ft.getStore().getId(), DataStoreInfo.class);
ElasticDataStore ds = (ElasticDataStore) dsInfo.getDataStore(null);
CatalogBuilder builder = new CatalogBuilder(catalog);
builder.setStore(dsInfo);
ElasticLayerConfiguration layerConfig;
layerConfig = new ElasticLayerConfiguration(_layerConfig);
layerConfig.setLayerName(_layerInfo.getName());
layerConfig.getAttributes().clear();
List<ElasticAttribute> attributes = _layerConfig.getAttributes();
layerConfig.getAttributes().addAll(attributes);
ds.setLayerConfiguration(layerConfig);
FeatureTypeInfo _typeInfo = (FeatureTypeInfo) _layerInfo.getResource();
typeInfo = builder.buildFeatureType(ds.getFeatureSource(qualifiedName));
typeInfo.setName(_layerInfo.getName());
typeInfo.getMetadata().put(ElasticLayerConfiguration.KEY, layerConfig);
typeInfo.setEnabled(_typeInfo.isEnabled());
typeInfo.setAdvertised(_typeInfo.isAdvertised());
typeInfo.setTitle(_typeInfo.getTitle());
typeInfo.setDescription(_typeInfo.getDescription());
typeInfo.setAbstract(_typeInfo.getAbstract());
typeInfo.getKeywords().addAll(_typeInfo.getKeywords());
typeInfo.getMetadataLinks().addAll(_typeInfo.getMetadataLinks());
typeInfo.getDataLinks().addAll(_typeInfo.getDataLinks());
typeInfo.setSRS(_typeInfo.getSRS());
typeInfo.setProjectionPolicy(_typeInfo.getProjectionPolicy());
typeInfo.setNativeBoundingBox(_typeInfo.getNativeBoundingBox());
typeInfo.setLatLonBoundingBox(_typeInfo.getLatLonBoundingBox());
typeInfo.setCircularArcPresent(_typeInfo.isCircularArcPresent());
typeInfo.setLinearizationTolerance(_typeInfo.getLinearizationTolerance());
layerInfo = builder.buildLayer(typeInfo);
builder.updateLayer(layerInfo, _layerInfo);
layerInfo.setName(_layerInfo.getName());
layerInfo.setResource(typeInfo);
} else {
// Update
typeInfo = (FeatureTypeInfo) layerInfo.getResource();
typeInfo.getMetadata().put(ElasticLayerConfiguration.KEY, _layerConfig);
}
}
}